package com.ziyueyuwen.xiniao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.suyeer.basic.util.EncryptUtil;
import com.suyeer.basic.util.ExecutorUtil;
import com.suyeer.basic.util.LogUtil;
import com.ziyueyuwen.xiniao.bean.subscription.TangLangRequestDTO;
import com.ziyueyuwen.xiniao.bean.subscription.ZySubscriptionMsgDO;
import com.ziyueyuwen.xiniao.bean.trial.TrialClassVO;
import com.ziyueyuwen.xiniao.dao.ZySubscriptionMsgMapper;
import com.ziyueyuwen.xiniao.dao.ZyTrialClassMapper;
import com.ziyueyuwen.xiniao.service.SubscriptionService;
import com.ziyueyuwen.xiniao.service.report.ReportService;
import com.ziyueyuwen.xiniao.util.TangLangUtil;
import org.apache.commons.collections4.map.LRUMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;

import static com.ziyueyuwen.xiniao.util.ConstUtil.*;

/**
 * @author jun 2019/1/7.
 */
@Service
public class SubscriptionServiceImpl implements SubscriptionService {

    @Autowired
    private ZySubscriptionMsgMapper zySubscriptionMsgMapper;
    @Autowired
    private ZyTrialClassMapper zyTrialClassMapper;
    @Autowired
    ReportService reportService;

    private final static String UPDATE_STU_CLASS_IN = "updateStuClassIn";
    private final static String ACCESS_CLASS_TIME = "accessClassTime";

    private static List<TangLangRequestDTO> tangLangRequestList = new ArrayList<>();

    static {
        TangLangRequestDTO tangLangRequest1 = new TangLangRequestDTO("http://tapi.bjmantis.net/api/classIn/", 6114, "开发环境");
        TangLangRequestDTO tangLangRequest2 = new TangLangRequestDTO("http://qaapi.bjmantis.net/api/classIn/", 7009, "QA测试环境");
        TangLangRequestDTO tangLangRequest3 = new TangLangRequestDTO("http://api.n4.bjmantis.net/api/classIn/", 3016, "生产环境");
        tangLangRequestList.add(tangLangRequest1);
        tangLangRequestList.add(tangLangRequest2);
        tangLangRequestList.add(tangLangRequest3);
    }

    private ExecutorService executorService = ExecutorUtil.newFixedThreadPool(10, "send_subscription_info_to_TangLang");

    @Override
    public void readData(String eeoNotifyStr) {
        try {
            JSONObject eeoNotifyObj = JSON.parseObject(eeoNotifyStr);
            String sId = eeoNotifyObj.getString("SID");
            String safeKey = eeoNotifyObj.getString("SafeKey");
            String cmd = eeoNotifyObj.getString("Cmd");
            long timeStamp = eeoNotifyObj.getLong("TimeStamp");
            String md5 = EncryptUtil.md5(SYS_CONFIG_DATA.getEeoSecret() + timeStamp);
            if (!((SYS_CONFIG_DATA.getEeoSid().equals(sId) && md5.equalsIgnoreCase(safeKey)))) {
                LogUtil.error("机构验证失败:{}, {}, {}, {}", sId, safeKey, timeStamp, eeoNotifyStr);
                return;
            }
            if (eeoNotifyObj.containsKey("StartTime")) {
                eeoNotifyObj.put("StartTime", eeoNotifyObj.getString("StartTime") + "000");
            }
            if (eeoNotifyObj.containsKey("CloseTime")) {
                eeoNotifyObj.put("CloseTime", eeoNotifyObj.getString("CloseTime") + "000");
            }
            ZySubscriptionMsgDO zySubscriptionMsg = new ZySubscriptionMsgDO();
            zySubscriptionMsg.setEeoCourseId(eeoNotifyObj.getInteger("CourseID"));
            zySubscriptionMsg.setEeoClassId(eeoNotifyObj.getInteger("ClassID"));
            zySubscriptionMsg.setCmd(cmd.toUpperCase());
            zySubscriptionMsg.setUserId(eeoNotifyObj.getString("LoginMobile"));
            zySubscriptionMsg.setuId(eeoNotifyObj.getString("UID"));
            zySubscriptionMsg.setMsg(eeoNotifyObj);
            zySubscriptionMsg.setStartTime(eeoNotifyObj.getDate("StartTime"));
            zySubscriptionMsg.setCloseTime(eeoNotifyObj.getDate("CloseTime"));
            sendToTangLang(eeoNotifyObj);
            zySubscriptionMsgMapper.add(zySubscriptionMsg);
            reportService.updateReportAward(zySubscriptionMsg);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error(e.getMessage());
        }
    }

    @Override
    public Boolean add(ZySubscriptionMsgDO zySubscriptionMsg) {
        return zySubscriptionMsgMapper.add(zySubscriptionMsg);
    }

    private LRUMap<Integer, Boolean> courseMap = new LRUMap<>();

    private void sendToTangLang(JSONObject eeoNotifyObj) {
        try {
            String cmd = eeoNotifyObj.getString("Cmd");
            JSONObject tangLangParams = new JSONObject();
            String funcName = null;
            if (CODE_INTO_CLASS.equals(cmd)) {
                tangLangParams.put("type", "intoClass");
                funcName = UPDATE_STU_CLASS_IN;
            }
            if (CODE_OUT_CLASS.equals(cmd)) {
                tangLangParams.put("type", "outClass");
                funcName = UPDATE_STU_CLASS_IN;
            }
            if (CODE_END.equalsIgnoreCase(cmd)) {
                tangLangParams.put("type", "end");
                funcName = ACCESS_CLASS_TIME;
            }
            if (!tangLangParams.containsKey("type")) {
                return;
            }
            Integer courseId = eeoNotifyObj.getInteger("CourseID");
            if (!courseMap.containsKey(courseId)) {
                TrialClassVO trialClassVO = zyTrialClassMapper.getByEeoCourseId(courseId);
                String courseName = trialClassVO != null ? trialClassVO.getClassName() : StringUtils.EMPTY;
                courseMap.put(courseId, courseName.contains(TANG_LANG_COURSE_NAME));
            }
            if (courseMap.get(courseId).equals(false)) {
                return;
            }
            tangLangParams.put("secretKey", SYS_CONFIG_DATA.getEeoSid());
            tangLangParams.put("jsonStr", eeoNotifyObj.toJSONString());
            LogUtil.info(JSON.toJSONString(tangLangParams));
            for (TangLangRequestDTO tangLangRequest : tangLangRequestList) {
                String finalFuncName = funcName;
                executorService.execute(() -> {
                    JSONObject params = new JSONObject();
                    params.putAll(tangLangParams);
                    params.put("companyId", tangLangRequest.getCompanyId());
                    JSONObject resultStr = TangLangUtil.sendRequestToTangLang(tangLangRequest.getUrl() + finalFuncName, params);
                    LogUtil.info("螳螂教育 {} 返回: {}", tangLangRequest.getDescribe(), resultStr.toJSONString());
                });
            }
        } catch (Exception e) {
            LogUtil.error(e);
        }
    }

    @Override
    public HashMap<String, Integer> getAwardInfo() {
        List<ZySubscriptionMsgDO> userList = zySubscriptionMsgMapper.listUidAndUserId();
        List<ZySubscriptionMsgDO> endDataList = zySubscriptionMsgMapper.listEndData();
        HashMap<String, String> userMap = new HashMap<>(2048);
        HashMap<String, Integer> awardMap = new HashMap<>(4096);
        for (ZySubscriptionMsgDO z : userList) {
            userMap.put(z.getuId(), z.getUserId());
        }
        for (ZySubscriptionMsgDO z : endDataList) {
            JSONObject msg = z.getMsg();
            try {
                JSONObject dataObj = msg.getJSONObject("Data");
                if (!dataObj.containsKey("awardEnd")) {
                    continue;
                }
                JSONObject awardObj = dataObj.getJSONObject("awardEnd");
                for (String uid : awardObj.keySet()) {
                    try {
                        if (userMap.containsKey(uid)) {
                            String userId = userMap.get(uid);
                            awardMap.put(z.getEeoClassId() + userId, awardObj.getJSONObject(uid).getInteger("Total"));
                        }
                    } catch (Exception e) {
                        LogUtil.error(e);
                    }
                }
            } catch (Exception e) {
                LogUtil.error(e);
            }
        }
        return awardMap;
    }

}
